function calculateDistance(point1, point2) {
  const x1 = point1[0];
  const y1 = point1[1];

  const x2 = point2[0];
  const y2 = point2[1];

  return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
}

function generateGraph(points, maxEdgeLength) {
  const graph = {};

  for (let i = 0; i < points.length; i++) {
    const point1 = points[i];
    let neighbors = [];

    for (let j = 0; j < points.length; j++) {
      if (i !== j) {
        const point2 = points[j];

        const distance = calculateDistance(point1, point2);

        if (distance <= maxEdgeLength) {
          neighbors.push({
            node: point2,
            weight: distance
          });
        }
      }
    }

    graph[point1] = neighbors;
  }

  return graph;
}

function dijkstra(graph, start, end) {
  const queue = [[0, start]]; // priority queue: [distance, node]
  const distances = { ...graph };
  const previous = {};
  let shortestPath = [];

  while (queue.length > 0) {
    const [distance, current] = queue.shift();

    if (current === end) {
      // backtracking to find the path
      let tempCurrent = current;
      while (tempCurrent !== start) {
        shortestPath.unshift(tempCurrent);
        tempCurrent = previous[tempCurrent];
      }
      shortestPath.unshift(start);
      return shortestPath;
    }

    for (let neighbor in graph[current]) {
      const weight = graph[current][neighbor].weight;
      if (!distances[neighbor] || distance + weight < distances[neighbor]) {
        distances[neighbor] = distance + weight;
        previous[neighbor] = current;
        queue.push([distance + weight, neighbor]);
      }
    }
  }

  return null; // no path found
}

const points = [
  [1, 5],
  [2, 6],
  [3, 6],
  [4, 6],
  // Add more points here
];

const maxEdgeLength = 5;
const graph = generateGraph(points, maxEdgeLength);

const startNode = points[0];
const endNode = points[points.length - 1];

console.log(dijkstra(graph, startNode, endNode));